package com.tintintech.sendmail;

import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import com.tintintech.sendmail.helper.DataHelper;
import com.tintintech.sendmail.helper.SendTask;
import com.tintintech.sendmail.util.MailStat;

public final class Processor {

	private static Processor _instance = null;

	public static Processor getInstance() {
		if (_instance == null) {
			_instance = new Processor();
		}
		return _instance;
	}

	private ExecutorService executor;
	private AtomicBoolean workLock;

	protected Processor() {
		int useFixedThreadPool = new Integer(Config.GLOBALS.get("useFixedThreadPool")).intValue();
		int maxThreadNum = new Integer(Config.GLOBALS.get("threadNum")).intValue();
		if (maxThreadNum <= 0) {
			maxThreadNum = 1;
		}
		if (useFixedThreadPool == 1) {
			this.executor = Executors.newFixedThreadPool(maxThreadNum);
		} else if (useFixedThreadPool == 0) {
			this.executor = Executors.newCachedThreadPool();
		} else if (useFixedThreadPool == 10) {
			this.executor = new ThreadPoolExecutor(
					1, maxThreadNum, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(maxThreadNum),
					new ThreadPoolExecutor.CallerRunsPolicy()
			);
			
		} else {
			System.out.println("config.xml-useFixedThreadPool-notConfig");
			System.exit(0);
		}

		this.workLock = new AtomicBoolean(false);
	}

	public void startWorker() {
		this.workLock.set(true);
		System.out.println("sendmail-process-worker-start");
		int taskSleepTime = new Integer(Config.GLOBALS.get("taskSleep")).intValue();
		while (this.workLock.get()) {
			try {
				Map<String, String> mailBox = DataHelper.MAILMAP_QUEUE.take();
				Runnable task = (Runnable)new SendTask(mailBox);
				TimeUnit.MILLISECONDS.sleep(taskSleepTime);
//				this.executor.execute(task);
				this.executor.submit(task);
				MailStat.MAIL_SEND_NUM.incrementAndGet();
			} catch (InterruptedException inte) {
				System.out.println("exception-interrupt");
			} catch (Throwable e) {
				System.out.println("exception-worker");
				e.printStackTrace();
			} finally {
				MailStat.MAIL_DISCARD_NUM_1.incrementAndGet();
			}
		}
	}
}
